/*
 * Copyright (c) 2017, Iotelligent Corporation
 * All rights reserved.
 *
 * Description:
 *
 *   iBAT2000 hardware timer header.
 */

#ifndef __IOT_HW_TIMER_H__
#define __IOT_HW_TIMER_H__

#include "stm32f4xx.h"
#include "iot_hw_types.h"
typedef void ( *FUN_SW_TIMER_CALLBACK_T )( void );

/* Software timer definitions */
#define SW_TIMER_TICK       10000   //10ms
#define SW_TIMER_NUMBER     10
#define SW_TIMER_EMPTY      (SW_TIMER_NUMBER + 1)

/* Counter tiemer decrement per us */
#define COUNTER_PER_US      48

/* Software timer mode */
enum
{
    /* fired only once */
    ONETIME_MODE,
    /* fired periodically */
    PERIODIC_MODE
};

typedef struct
{
    uint8_t loop;
    uint8_t en;
    uint8_t valid;
    uint32_t load;
    uint32_t current;
    FUN_SW_TIMER_CALLBACK_T sw_timer_callback;
} SW_TIMER_T;


#define TIMER_SW 						ADVANCE_TIM1
#define TIMER_COUNTER    		ADVANCE_TIM3

#define ADVANCE_TIM1           		TIM1
#define ADVANCE_TIM1_CLK       		RCC_APB2Periph_TIM1

#define ADVANCE_TIM1_IRQn					TIM1_UP_TIM10_IRQn
#define ADVANCE_TIM1_IRQHandler    TIM1_UP_TIM10_IRQHandler


#define ADVANCE_TIM2           		TIM2
#define ADVANCE_TIM2_CLK       		RCC_APB1Periph_TIM2

#define ADVANCE_TIM2_IRQn					TIM2_IRQn
#define ADVANCE_TIM2_IRQHandler    TIM2_IRQHandler


#define ADVANCE_TIM3           		TIM3
#define ADVANCE_TIM3_CLK       		RCC_APB1Periph_TIM3

#define ADVANCE_TIM3_IRQn					TIM3_IRQn
#define ADVANCE_TIM3_IRQHandler    TIM3_IRQHandler


#define ADVANCE_TIM4           		TIM4
#define ADVANCE_TIM4_CLK       		RCC_APB1Periph_TIM4

#define ADVANCE_TIM4_IRQn					TIM4_IRQn
#define ADVANCE_TIM4_IRQHandler    TIM4_IRQHandler

typedef struct
{
    uint32_t counter_tick_high;         /* high 32bit of counter value */
    uint32_t counter_timer_rate_hz;     /* counts per us */
    uint32_t counter_timer_index;
    uint64_t counter_start_value;
} COUNTER_TIMER_T;

extern FUN_INT_CALLBACK_T timer0_int_callback;
extern FUN_INT_CALLBACK_T timer1_int_callback;

uint32_t sw_timer_get_tick( void );
int sw_timer_add( uint32_t ms, uint8_t loop,
                  FUN_SW_TIMER_CALLBACK_T sw_timer_callback,
                  uint8_t *p_timer_id );
int sw_timer_update( uint8_t timer_id, uint32_t ms, uint8_t loop );
int sw_timer_remove( uint8_t timer_id );
int sw_timer_get_load( uint8_t timer_id, uint32_t *load );
int sw_timer_get_current( uint8_t timer_id, uint32_t *current );
int sw_timer_set_current( uint8_t timer_id, uint32_t current );
int sw_timer_reload( uint8_t timer_id );
int sw_timer_start( uint8_t timer_id );
int sw_timer_stop( uint8_t timer_id );
void counter_start( void );
int counter_is_timeout( uint32_t us );
uint32_t counter_system_time( void );
void counter_get_curr_timestamp( uint32_t *timestamp );
uint32_t counter_diff_us( uint32_t timestamp );
void timer_init( void );

#endif /* __IOT_HW_TIMER_H__ */
